#include "../include/netdisk.h"

extern extra_data_t globaltoken;

int clientLogin(const char *ip, const char *port)
{
    int sockfd = 0;
    // sockfd = tcpConnect(ip, port);
    // if (sockfd < 0)
    // { // 连接失败
    //     close(sockfd);
    // }
    int epfd = epoll_create(1);
    epollAdd(epfd, STDIN_FILENO); // 监听键盘输入

    train_t train = {0};
    char buf[4096] = {0};
    client_t client = {0};
    char salt[1024] = {0};

    int loginFlag = 0;     // 0未连接服务端，1已连接服务端
    int passwordFlag = 0;  // 控制消息输出
    int nameInput = 0;     // 0用户名未输入，1用户名已输入
    int passwordInput = 0; // 0密码未输入，1密码已输入
    int getsalt = 0;       // 0盐值未获取，1盐值已获取
    int linkCount = 0;     // 连接计数，至多连接5次
    int login_or_regiter = 0;

    struct epoll_event readyset[1024];
    // 登录过程
    while (1)
    {
        // epollAdd(epfd, sockfd); // 监听服务端消息
        if (loginFlag == 0)
        { // 未连接服务端，准备连接
            if (passwordFlag == 0)
            {
                printf("正在连接服务端......\n");
            }
            sockfd = tcpConnect(ip, port);
            epollAdd(epfd, sockfd); // 监听服务端消息
            if (sockfd < 0)
            { // 连接失败，继续连接
                epollDel(epfd, sockfd);
                close(sockfd);
                loginFlag = 0;
                sleep(1);
                linkCount++;
                if (linkCount == 5)
                { // 连接次数过多, 服务端断开
                    return -1;
                }
                continue;
            }
            if (passwordFlag == 0)
            {
                printf("连接服务端成功......\n");
            }
            // printf("\n请输入账号密码\n");
            if (login_or_regiter == 0)
            {
                printf("登录(1), 注册(2)\n");
            }
            nameInput = 0;     // 0用户名未输入，1用户名已输入
            passwordInput = 0; // 0密码未输入，1密码已输入
            passwordFlag = 1;
            loginFlag = 1;
        }

        if (login_or_regiter > 0)
        {
            if (nameInput == 0)
            {
                printf("请输入用户名: ");
                fflush(stdout);
            }
            if (getsalt == 1 && nameInput == 1 && passwordInput == 0)
            {
                printf("请输入密码: ");
                fflush(stdout);
            }
        }

        int readynum = epoll_wait(epfd, readyset, 1024, -1); // -1永久等待
        for (int i = 0; i < readynum; i++)
        {
            if (readyset[i].data.fd == STDIN_FILENO)
            { // 输入密码
                memset(&buf, 0, sizeof(buf));
                memset(&train, 0, sizeof(train));
                int ret = read(STDIN_FILENO, buf, sizeof(buf));
                if (ret <= 0)
                { // ctrl + d
                    printf("客户退出!\n");
                    return 1;
                }
                if (login_or_regiter == 0)
                {
                    buf[strlen(buf) - 1] = '\0';
                    int ret = commandCheck(buf, &train);
                    if (ret == -1)
                    {
                        printf("请重新输入:\n");
                        break;
                    }
                    // printf("test: train.cmd = |%d| train.length = |%d| train.data = |%s|\n", train.cmdstat, train.length, train.data);
                    if (train.cmdstat == LOGIN)
                    {
                        login_or_regiter = 1;
                        break;
                    }
                    else if (train.cmdstat == RIGIST)
                    {
                        login_or_regiter = 2;
                        break;
                    }
                    else
                    {
                        printf("请重新输入:\n");
                        break;
                    }
                }

                else if (login_or_regiter > 0)
                {
                    if (nameInput == 0)
                    { // 用户名未输入
                        memset(client.Name, 0, sizeof(client.Name));
                        strcpy(client.Name, strtok(buf, " \n"));
                        if (login_or_regiter == 1)
                        {
                            train.cmdstat = LOGIN;
                        }
                        else if (login_or_regiter == 2)
                        {
                            train.cmdstat = RIGIST;
                        }
                        train.length = sizeof(client.Name); // 1024
                        memcpy(train.data, &client.Name, train.length);
                        // 先发用户名
                        send_train(sockfd, &train);
                        // printf("用户名: |%s|\n", train.data);
                        nameInput = 1;
                        continue;
                    }
                    if (passwordInput == 0)
                    { // 密码未输入
                        memset(client.Password, 0, sizeof(client.Password));
                        strcpy(client.Password, strtok(buf, " \n"));
                        // printf("未加密: |%s|\n", client.Password);
                        // 加密
                        memcpy(client.Password, crypt(client.Password, salt), sizeof(client.Password));
                        // printf("已加密: |%s|\n", client.Password);
                        train.cmdstat = HASH;
                        train.length = sizeof(client.Password); // 1024
                        memcpy(train.data, &client.Password, train.length);
                        // 再发密码
                        send_train(sockfd, &train);
                        passwordInput = 1;
                    }
                }
            }
            else if (readyset[i].data.fd == sockfd)
            {
                train_t trainRecv = {0};
                // printf("test: sokcfd响应\n");
                // 收火车
                int ret = recv_train(sockfd, &trainRecv);
                if (ret < 0)
                {
                    printf("客户端test: 断开重连\n");
                    epollDel(epfd, sockfd);
                    close(sockfd);
                    loginFlag = 0;
                    continue;
                }
                if (trainRecv.cmdstat & HASH)
                { // 接收盐值
                    memset(salt, 0, sizeof(salt));
                    memcpy(salt, trainRecv.data, trainRecv.length);
                    salt[trainRecv.length] = '\0';
                    // printf("客户端测试: salt = |%s|\n", salt);
                    getsalt = 1;
                    continue;
                }
                else if (trainRecv.cmdstat & TOKEN)
                { // 接收TOKEN, 接收token说明登录成功
                    extra_data_t *newToken = (extra_data_t *)trainRecv.data;

                    memcpy(&globaltoken, newToken, sizeof(extra_data_t));
                    // printf("新增用户: id:|%d|, usrname:|%s|, usrtoken:|%s|\n", globaltoken.cur_dir_id, globaltoken.user, globaltoken.token);
                    // printf("客户端: 登录成功!\n");
                    // 登录成功自动调用ls命令
                    // 。。。。。。
                    return sockfd;
                }
                else if (trainRecv.cmdstat == (LOGIN | RES) && passwordInput == 0)
                { // 用户名不存在
                    printf("服务端test: %s\n", trainRecv.data);
                    printf("用户名不存在\n");
                    nameInput = 0;
                    continue;
                }
                else if (trainRecv.cmdstat == (RIGIST | RES) && passwordInput == 0)
                { // 用户名重复
                    printf("服务端test: %s\n", trainRecv.data);
                    printf("用户名重复\n");
                    nameInput = 0;
                    continue;
                }
                else if (trainRecv.cmdstat == (LOGIN | RES) && nameInput == 1)
                { // 密码错误
                    printf("服务端test: %s\n", trainRecv.data);
                    printf("密码错误\n");
                    nameInput = 0;
                    passwordInput = 0;
                    continue;
                }
            }
        }
    }
}